package cz.muni.fi.pa165.hauntedhouses.util;

import cz.muni.fi.pa165.hauntedhouses.dto.AbilityDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.AccountDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.GhostDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.HouseDTO;
import cz.muni.fi.pa165.hauntedhouses.dto.HumanDTO;
import cz.muni.fi.pa165.hauntedhouses.entity.Ability;
import cz.muni.fi.pa165.hauntedhouses.entity.Account;
import cz.muni.fi.pa165.hauntedhouses.entity.Ghost;
import cz.muni.fi.pa165.hauntedhouses.entity.House;
import cz.muni.fi.pa165.hauntedhouses.entity.Human;
import java.util.ArrayList;
import java.util.List;

/**
 * A very *cool* class allowing you to transfer any entity object to DTO or any
 * DTO back to entity. This translation is used on service layer.
 *
 * @author Petr Suchý (team "leader" -hahaaa...) & Siliarus (our team joker :D)
 * ---..*cool*
 */
public class DTOAndDAOMapper {

    /**
     * Transfers a DTO Human to entity Human object
     *
     * @param humanDto DTO human object to be transfered
     * @return entity Human object with no validation
     */
    public static Human DTOHumanToEntityHuman(HumanDTO humanDto) {
        if (humanDto == null) {
            return null;
        }
        Human human = new Human();

        human.setDescription(humanDto.getDescription());
        human.setHome(DTOHouseToEntityHouse(humanDto.getHome()));
        human.setName(humanDto.getName());
        human.setPsyche(humanDto.getPsyche());
        human.setId(humanDto.getId());
        return human;
    }

    /**
     * Transfers a DTO Human to entity Human object (version for mappers of
     * house)
     *
     * @param humanDto DTO human object to be transfered
     * @param house house to be set as home
     * @return entity Human object with no validation
     */
    public static Human DTOHumanToEntityHuman(HumanDTO humanDto, House house) {
        if (humanDto == null) {
            return null;
        }
        Human human = new Human();

        human.setDescription(humanDto.getDescription());
        human.setHome(house);
        human.setName(humanDto.getName());
        human.setPsyche(humanDto.getPsyche());
        human.setId(humanDto.getId());
        return human;
    }

    /**
     * Transfers a Human entity object to DTO object
     *
     * @param human Human to be transfered to DTO object
     * @return Human dto object with no validation
     */
    public static HumanDTO HumanEntityToDTOHuman(Human human) {
        if (human == null) {
            return null;
        }

        HumanDTO humanDto = new HumanDTO();

        humanDto.setDescription(human.getDescription());
        humanDto.setHome(HouseEntityToDTOHouse(human.getHome()));
        humanDto.setName(human.getName());
        humanDto.setPsyche(human.getPsyche());
        humanDto.setId(human.getId());
        return humanDto;
    }

    /**
     * Transfers a Human entity object to DTO object (version for mappers of
     * house)
     *
     * @param human Human to be transfered to DTO object
     * @param house house to be set as home
     * @return Human dto object with no validation
     */
    public static HumanDTO HumanEntityToDTOHuman(Human human, HouseDTO houseDTO) {
        if (human == null) {
            return null;
        }

        HumanDTO humanDto = new HumanDTO();
        humanDto.setDescription(human.getDescription());
        humanDto.setHome(houseDTO);
        humanDto.setName(human.getName());
        humanDto.setPsyche(human.getPsyche());
        humanDto.setId(human.getId());
        return humanDto;
    }

    /**
     * Transfers a Ghost DTO to Entity Ghost object
     *
     * @param gDto ghost DTO to be transfered
     * @return Ghost entity object
     */
    public static Ghost DTOGhostToEntityGhost(GhostDTO gDto) {
        if (gDto == null) {
            return null;
        }

        Ghost ghost = new Ghost();
        List<Ability> list = new ArrayList<>();
        for (AbilityDTO a : gDto.getAbilities()) {
            list.add(DTOAndDAOMapper.DTOAbilityToEntityAbility(a));
        }
        ghost.setAbilities(list);
        ghost.setAbilityType(gDto.getAbilityType());
        ghost.setDescription(gDto.getDescription());
        ghost.setName(gDto.getName());
        ghost.setExperience(gDto.getExperience());
        ghost.setLvl(gDto.getLvl());
        ghost.setHome(DTOHouseToEntityHouse(gDto.getHome()));
        ghost.setId(gDto.getId());
        ghost.setLastHaunted(gDto.getLastHaunted());
        return ghost;
    }

    /**
     * Transfers a Ghost DTO to Entity Ghost object (version for mappers of
     * house)
     *
     * @param gDto ghost DTO to be transfered
     * @param house house to be set as home
     * @return Ghost entity object
     */
    public static Ghost DTOGhostToEntityGhost(GhostDTO gDto, House house) {
        if (gDto == null) {
            return null;
        }

        Ghost ghost = new Ghost();
        List<Ability> list = new ArrayList<>();
        for (AbilityDTO a : gDto.getAbilities()) {
            list.add(DTOAndDAOMapper.DTOAbilityToEntityAbility(a));
        }
        ghost.setAbilities(list);
        ghost.setAbilityType(gDto.getAbilityType());
        ghost.setDescription(gDto.getDescription());
        ghost.setName(gDto.getName());
        ghost.setExperience(gDto.getExperience());
        ghost.setLvl(gDto.getLvl());
        ghost.setHome(house);
        ghost.setId(gDto.getId());
        ghost.setLastHaunted(gDto.getLastHaunted());
        return ghost;
    }

    /**
     * Transfers a House DTO to House entity object
     *
     * @param hDto DTO to be transfered
     * @return House entity object
     */
    public static House DTOHouseToEntityHouse(HouseDTO hDto) {
        if (hDto == null) {
            return null;
        }

        House house = new House();

        house.setAddress(hDto.getAddress());
        house.setGhostCapacity(hDto.getGhostCapacity());
        List<Ghost> list = new ArrayList<>();
        for (GhostDTO g : hDto.getGhosts()) {
            list.add(DTOAndDAOMapper.DTOGhostToEntityGhost(g, house));
        }
        house.setGhosts(list);
        house.setHistory(hDto.getHistory());
        house.setHumanCapacity(hDto.getHumanCapacity());
        List<Human> list2 = new ArrayList<>();
        for (HumanDTO h : hDto.getHumans()) {
            list2.add(DTOAndDAOMapper.DTOHumanToEntityHuman(h, house));
        }

        house.setHumans(list2);
        house.setId(hDto.getId());
        house.setName(hDto.getName());
        return house;
    }

    /**
     * Transfers an AbilityDTO to Ability entity object
     *
     * @param aDto an Ability to be transfered
     * @return Ability entity object
     */
    public static Ability DTOAbilityToEntityAbility(AbilityDTO aDto) {
        if (aDto == null) {
            return null;
        }

        Ability ability = new Ability();

        ability.setAbilityLevel(aDto.getAbilityLevel());
        ability.setAbilityType(aDto.getAbilityType());
        ability.setDamage(aDto.getDamage());
        ability.setDescription(aDto.getDescription());
        ability.setId(aDto.getId());
        ability.setName(aDto.getName());
        return ability;
    }

    /**
     * Transfers a Ghost entity to DTO
     *
     * @param ghost Ghost to be transfered
     * @return Ghost DTO
     */
    public static GhostDTO GhostEntityToDTOGhost(Ghost ghost) {
        if (ghost == null) {
            return null;
        }

        GhostDTO dto = new GhostDTO();
        List<AbilityDTO> list = new ArrayList<>();
        for (Ability a : ghost.getAbilities()) {
            list.add(DTOAndDAOMapper.AbilityEntityToDTOAbility(a));
        }
        dto.setAbilities(list);
        dto.setAbilityType(ghost.getAbilityType());
        dto.setDescription(ghost.getDescription());
        dto.setExperience(ghost.getExperience());
        dto.setHome(HouseEntityToDTOHouse(ghost.getHome()));
        dto.setId(ghost.getId());
        dto.setLastHaunted(ghost.getLastHaunted());
        dto.setLvl(ghost.getLvl());
        dto.setName(ghost.getName());
        return dto;
    }

    /**
     * Transfers a Ghost entity to DTO (version for mappers of house)
     *
     * @param ghost Ghost to be transfered
     * @param house house to be set as home
     * @return Ghost DTO
     */
    public static GhostDTO GhostEntityToDTOGhost(Ghost ghost, HouseDTO houseDTO) {
        if (ghost == null) {
            return null;
        }

        GhostDTO dto = new GhostDTO();
        List<AbilityDTO> list = new ArrayList<>();
        for (Ability a : ghost.getAbilities()) {
            list.add(DTOAndDAOMapper.AbilityEntityToDTOAbility(a));
        }
        dto.setAbilities(list);
        dto.setAbilityType(ghost.getAbilityType());
        dto.setDescription(ghost.getDescription());
        dto.setExperience(ghost.getExperience());
        dto.setHome(houseDTO);
        dto.setId(ghost.getId());
        dto.setLastHaunted(ghost.getLastHaunted());
        dto.setLvl(ghost.getLvl());
        dto.setName(ghost.getName());
        return dto;
    }

    /**
     * Transfers a House entity object to House DTO
     *
     * @param house House to be transfered
     * @return House DTO
     */
    public static HouseDTO HouseEntityToDTOHouse(House house) {
        if (house == null) {
            return null;
        }
        HouseDTO dto = new HouseDTO();

        dto.setAddress(house.getAddress());
        dto.setGhostCapacity(house.getGhostCapacity());
        List<GhostDTO> list = new ArrayList<>();
        for (Ghost g : house.getGhosts()) {
            list.add(DTOAndDAOMapper.GhostEntityToDTOGhost(g, dto));
        }
        dto.setGhosts(list);
        dto.setHistory(house.getHistory());
        dto.setHumanCapacity(house.getHumanCapacity());
        List<HumanDTO> list2 = new ArrayList<>();
        for (Human h : house.getHumans()) {
            list2.add(DTOAndDAOMapper.HumanEntityToDTOHuman(h, dto));
        }
        dto.setHumans(list2);
        dto.setId(house.getId());
        dto.setName(house.getName());
        return dto;
    }

    /**
     * Transfers an Ability entity object to DTO
     *
     * @param ability Ability to be transfered
     * @return Ability DTO
     */
    public static AbilityDTO AbilityEntityToDTOAbility(Ability ability) {
        if (ability == null) {
            return null;
        }
        AbilityDTO dto = new AbilityDTO();
        dto.setAbilityLevel(ability.getAbilityLevel());
        dto.setAbilityType(ability.getAbilityType());
        dto.setDamage(ability.getDamage());
        dto.setDescription(ability.getDescription());
        dto.setId(ability.getId());
        dto.setName(ability.getName());
        return dto;
    }
    
    /**A method for converting Account to DTO Account
     * 
     * @param acc acount to be converted
     * @return AccountDTO object
     */
    public static AccountDTO AccountEntityToDTOAccount (Account acc) {
        if (acc == null) {
            return null;
        }
        AccountDTO dto = new AccountDTO();
        dto.setId(acc.getId());
        dto.setIsAdmin(acc.getIsAdmin());
        dto.setPassword(acc.getPassword());
        dto.setUsername(acc.getUsername());
        return dto;
    }
    
    /**A method convertin DTO Account into Account
     * 
     * @param dtoAcc DTO object to be converted
     * @return Account object
     */
    public static Account DTOAccountToEntityAccount (AccountDTO dtoAcc) {
        Account acc = new Account();
        acc.setId(dtoAcc.getId());
        acc.setIsAdmin(dtoAcc.getIsAdmin());
        acc.setPassword(dtoAcc.getPassword());
        acc.setUsername(dtoAcc.getUsername());
        return acc;
    }
}
